package v8.Class_Isolate is
   type Isolate (<>) is tagged limited private;
   type Pointer is access all Isolate;
   -- Isolate represents an isolated instance of the V8 engine.  V8
   -- isolates have completely separate states.  Objects from one isolate
   -- must not be used in other isolates.  When V8 is initialized a
   -- default isolate is implicitly created and entered.  The embedder
   -- can create additional isolates and use them in parallel in multiple
   -- threads.  An isolate can be entered by at most one thread at any
   -- given time.  The Locker/Unlocker API can be used to synchronize.

   procedure Enter (this : in out Isolate);
   -- Sets this isolate as the entered one for the current thread.
   -- Saves the previously entered one (if any), so that it can be
   -- restored when exiting.  Re-entering an isolate is allowed.

   procedure Leave (this : in out Isolate);
   -- Exits this isolate by restoring the previously entered one in the
   -- current thread.  The isolate may still stay the same, if it was
   -- entered more than once.
   --
   -- Requires: this == Isolate::GetCurrent().

   procedure Dispose (this : in out Isolate);
   -- Disposes the isolate.  The isolate must not be entered by any
   -- thread to be disposable.

   procedure Set_Data (this : in out Isolate; data : Address);
   -- Associate embedder-specific data with the isolate

   function Get_Data (this : Isolate) return Address;
   -- Retrive embedder-specific data from the isolate.
   -- Returns NULL if SetData has never been called.

   function Create return Pointer;
   -- Creates a new isolate.  Does not change the currently entered
   -- isolate.
   --
   -- When an isolate is no longer used its resources should be freed
   -- by calling Dispose().  Using the delete operator is not allowed.

   function Get_Current return Pointer;
   -- Returns the entered isolate for the current thread or NULL in
   -- case there is no current isolate.

   type Scope (owner : access Isolate) is limited private;
   -- provide convenient to auto enter / leave

private
   type Isolate is tagged limited null record;

   type Scope (owner : access Isolate) is new Ada.Finalization.Limited_Controlled with null record;
   procedure Initialize (this : in out Scope);
   procedure Finalize(this : in out Scope);

   pragma Import (CPP, Create, "_ZN2v87Isolate3NewEv");
   pragma Import (CPP, Get_Current, "_ZN2v87Isolate10GetCurrentEv");
   pragma Import (CPP, Enter, "_ZN2v87Isolate5EnterEv");
   pragma Import (CPP, Set_Data, "_ZN2v87Isolate7SetDataEPv");
   pragma Import (CPP, Leave, "_ZN2v87Isolate4ExitEv");
   pragma Import (CPP, Dispose, "_ZN2v87Isolate7DisposeEv");
   pragma Import (CPP, Get_Data, "_ZN2v87Isolate7GetDataEv");
end v8.Class_Isolate;
